home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Newswatcher 2.0b22 / NW Source / Source / next.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-19  |  9.7 KB  |  374 lines  |  [TEXT/MMCC]

  1. /*----------------------------------------------------------------------------
  2.  
  3.     next.c
  4.  
  5.     This module handles the next article, thread, and group commands.
  6.     
  7.     Copyright © 1994, Northwestern University.
  8.  
  9. ----------------------------------------------------------------------------*/
  10.  
  11. #include "glob.h"
  12. #include "article.h"
  13. #include "newswatcher.h"
  14. #include "mark.h"
  15. #include "next.h"
  16. #include "subject.h"
  17. #include "listutil.h"
  18. #include "dialog.h"
  19. #include "dummy.h"
  20.  
  21.  
  22.  
  23. /*----------------------------------------------------------------------------
  24.     OpenNextUnreadGroup 
  25.     
  26.     Open the subject window for the next group with unread articles in a 
  27.     group window.
  28.             
  29.     Entry:    wind = pointer to group window.
  30.             theCell = the cell in the group window at which to start
  31.                 the search for the next group with unread articles.
  32.                 
  33.     Exit:    function result = error code.
  34. ----------------------------------------------------------------------------*/
  35.  
  36. static OSErr OpenNextUnreadGroup (WindowPtr wind, Cell theCell)
  37. {
  38.     TWindow **info;
  39.     TGroupWindowKind groupKind;
  40.     TGroup **groupArray, theGroup;
  41.     ListHandle theList;
  42.     short numCells, cellDataLen, index;
  43.     OSErr err = noErr;
  44.     Boolean hasArts;
  45.  
  46.     info = (TWindow**)GetWRefCon(wind);
  47.     groupKind = (**info).groupKind;
  48.     groupArray = (**info).groupArray;
  49.     theList = (**info).theList;
  50.     numCells = (**theList).dataBounds.bottom;
  51.     for (; theCell.v < numCells; theCell.v++) {
  52.         cellDataLen = 2;
  53.         LGetCell(&index, &cellDataLen, theCell, theList);
  54.         theGroup = (*groupArray)[index];
  55.         if ((groupKind == kUserGroup && theGroup.unread != nil) ||
  56.             (groupKind != kUserGroup && theGroup.lastMess >= theGroup.firstMess)) 
  57.         {
  58.             SelectSingleListItem(theList, theCell);
  59.             HandleUpdate(wind);
  60.             MyLAutoScroll(theList);
  61.             err = OpenGroupCell(wind, theCell, gPrefs.maxFetch, &hasArts);
  62.             if (err != noErr) return err;
  63.             if (err == noErr && hasArts) return noErr;
  64.         }
  65.     }
  66.     SysBeep(0);
  67.     return noErr;
  68. }
  69.  
  70.  
  71.  
  72. /*----------------------------------------------------------------------------
  73.     OpenNextUnreadArticle 
  74.     
  75.     Open the article window for the next unread article in a subject window.
  76.             
  77.     Entry:    wind = pointer to subject window.
  78.             theCell = the cell in the subject window at which to start
  79.                 the search for the next unread article.
  80.             threadOrdinal = ordinal of article within thread at which
  81.                 to start the search if the cell is a collapsed thread.
  82.             reuse = pointer to article window to be reused, or nil to
  83.                 open new article window.
  84.             onlySelect = true to only select the next unrread article
  85.                 in the subject window, but not open it.
  86.                 
  87.     Exit:    function result = error code.
  88. ----------------------------------------------------------------------------*/
  89.  
  90. static OSErr OpenNextUnreadArticle (WindowPtr wind, Cell theCell, 
  91.     short threadOrdinal, WindowPtr reuse, Boolean onlySelect)
  92. {
  93.     TWindow **info;
  94.     TSubject **subjectArray;
  95.     ListHandle theList;
  96.     short numCells, cellDataLen, index, i;
  97.     Boolean collapsed;
  98.     WindowPtr child, parent;
  99.     OSErr err = noErr;
  100.  
  101.     info = (TWindow**)GetWRefCon(wind);
  102.     subjectArray = (**info).subjectArray;
  103.     theList = (**info).theList;
  104.     numCells = (**theList).dataBounds.bottom;
  105.     while (theCell.v < numCells) {
  106.         cellDataLen = 2;
  107.         LGetCell(&index, &cellDataLen, theCell, theList);
  108.         if (threadOrdinal > (*subjectArray)[index].threadLength) {
  109.             theCell.v++;
  110.             threadOrdinal = 1;
  111.         } else {
  112.             collapsed = (*subjectArray)[index].collapsed;
  113.             if (collapsed) 
  114.                 for (i = 1; i < threadOrdinal; i++) 
  115.                     index = (*subjectArray)[index].nextInThread;
  116.             if (!(*subjectArray)[index].read) { 
  117.                 SelectSingleListItem(theList, theCell);
  118.                 HandleUpdate(wind);
  119.                 MyLAutoScroll(theList);
  120.                 if (onlySelect) return noErr;
  121.                 err = OpenSubjectCell(wind, theCell, threadOrdinal, reuse, &child);
  122.                 if (err != noErr) return err;
  123.                 if (child != nil) return noErr;
  124.             }
  125.             if (collapsed) {
  126.                 threadOrdinal++;
  127.             } else {
  128.                 theCell.v++;
  129.                 threadOrdinal = 1;
  130.             }
  131.         }
  132.     }
  133.     if (reuse != nil) DoClose(reuse);
  134.     if (gPrefs.beepAtEndOfGroup) {
  135.         SysBeep(0);
  136.     } else {
  137.         parent = (**info).parentWindow;
  138.         index = (**info).parentGroup;
  139.         err = DoClose(wind);
  140.         if (err != noErr) return err;
  141.         wind = parent;
  142.         FindParentCell(wind, index, &theCell);
  143.         theCell.v++;
  144.         return OpenNextUnreadGroup(wind, theCell);
  145.     }
  146.     return noErr;
  147. }
  148.  
  149.  
  150.  
  151. /*----------------------------------------------------------------------------
  152.     DoNextArticle 
  153.     
  154.     Handle the "Next Article" command.
  155.             
  156.     Entry:    wind = pointer to article, subject, or group window.
  157.     
  158.     Exit:    function result = error code.
  159. ----------------------------------------------------------------------------*/
  160.  
  161. OSErr DoNextArticle (WindowPtr wind)
  162. {
  163.     TWindow **info;
  164.     WindowPtr parent;
  165.     short index, threadOrdinal;
  166.     TSubject **subjectArray, theSubject;
  167.     Cell theCell;
  168.     Boolean returnToSubjectWindow = false;
  169.     OSErr err = noErr;
  170.     
  171.     info = (TWindow**)GetWRefCon(wind);
  172.     
  173.     switch ((**info).kind) {
  174.     
  175.         case kArticle:
  176.         
  177.             parent = (**info).parentWindow;
  178.             if (parent == nil) return noErr;
  179.             index = (**info).parentSubject;
  180.             info = (TWindow**)GetWRefCon(parent);
  181.             subjectArray = (**info).subjectArray;
  182.             theSubject = (*subjectArray)[index];
  183.             if (theSubject.collapsed) {
  184.                 FindParentCell(parent, theSubject.threadHeadIndex, &theCell);
  185.                 threadOrdinal = theSubject.threadOrdinal + 1;
  186.             } else {
  187.                 FindParentCell(parent, index, &theCell);
  188.                 theCell.v++;
  189.                 threadOrdinal = 1;
  190.             }
  191.             
  192.             if (gPrefs.returnToSubjectWindow) {
  193.                 returnToSubjectWindow = true;
  194.                 while (true) {
  195.                     if (theSubject.threadOrdinal == theSubject.threadLength) break;
  196.                     theSubject = (*subjectArray)[theSubject.nextInThread];
  197.                     if (!theSubject.read) {
  198.                         returnToSubjectWindow = false;
  199.                         break;
  200.                     }
  201.                 }
  202.             }
  203.             
  204.             if (returnToSubjectWindow) {
  205.                 err = DoClose(wind);
  206.                 if (err != noErr) return err;
  207.                 return OpenNextUnreadArticle(parent, theCell, threadOrdinal, nil, true);
  208.             } else if (gPrefs.reuseArticleWinds) {
  209.                 return OpenNextUnreadArticle(parent, theCell, threadOrdinal, wind, false);
  210.             } else {
  211.                 err = DoClose(wind);
  212.                 if (err != noErr) return err;
  213.                 err = ShowDummyWindow();
  214.                 if (err != noErr) return err;
  215.                 err = OpenNextUnreadArticle(parent, theCell, threadOrdinal, nil, false);
  216.                 HideDummyWindow();
  217.                 return err;
  218.             }
  219.             
  220.         case kSubject:
  221.         
  222.             SetPt(&theCell, 0, 0);
  223.             LGetSelect(true, &theCell, (**info).theList);
  224.             threadOrdinal = 1;
  225.             return OpenNextUnreadArticle(wind, theCell, threadOrdinal, nil, false);
  226.             
  227.         case kGroup:
  228.         
  229.             SetPt(&theCell, 0, 0);
  230.             LGetSelect(true, &theCell, (**info).theList);
  231.             return OpenNextUnreadGroup(wind, theCell);
  232.             
  233.     }
  234.     return noErr;
  235. }
  236.  
  237.  
  238.  
  239. /*----------------------------------------------------------------------------
  240.     DoNextThread 
  241.     
  242.     Handle the "Next Thread" command.
  243.             
  244.     Entry:    wind = pointer to article, subject, or group window.
  245.     
  246.     Exit:    function result = error code.
  247. ----------------------------------------------------------------------------*/
  248.  
  249. OSErr DoNextThread (WindowPtr wind)
  250. {
  251.     TWindow **info;
  252.     WindowPtr parent;
  253.     short index, cellDataLen;
  254.     TSubject **subjectArray, theSubject;
  255.     Cell theCell;
  256.     ListHandle theList;
  257.     OSErr err = noErr;
  258.     
  259.     info = (TWindow**)GetWRefCon(wind);
  260.     
  261.     switch ((**info).kind) {
  262.     
  263.         case kArticle:
  264.         
  265.             parent = (**info).parentWindow;
  266.             if (parent == nil) return noErr;
  267.             index = (**info).parentSubject;
  268.             info = (TWindow**)GetWRefCon(parent);
  269.             subjectArray = (**info).subjectArray;
  270.             theSubject = (*subjectArray)[index];
  271.             MarkThread(parent, theSubject.threadHeadIndex, true);
  272.             FindParentCell(parent, theSubject.threadHeadIndex, &theCell);
  273.             if (theSubject.collapsed) {
  274.                 theCell.v++;
  275.             } else {
  276.                 theCell.v += theSubject.threadLength;
  277.             }
  278.             
  279.             if (gPrefs.reuseArticleWinds) {
  280.                 return OpenNextUnreadArticle(parent, theCell, 1, wind, false);
  281.             } else {
  282.                 err = DoClose(wind);
  283.                 if (err != noErr) return err;
  284.                 err = ShowDummyWindow();
  285.                 if (err != noErr) return err;
  286.                 err = OpenNextUnreadArticle(parent, theCell, 1, nil, false);
  287.                 HideDummyWindow();
  288.                 return err;
  289.             }
  290.             
  291.         case kSubject:
  292.         
  293.             theList = (**info).theList;
  294.             subjectArray = (**info).subjectArray;
  295.             SetPt(&theCell, 0, 0);
  296.             if (LGetSelect(true, &theCell, theList)) {
  297.                 cellDataLen = 2;
  298.                 LGetCell(&index, &cellDataLen, theCell, theList);
  299.                 theSubject = (*subjectArray)[index];
  300.                 MarkThread(wind, theSubject.threadHeadIndex, true);
  301.                 if (theSubject.collapsed) {
  302.                     theCell.v++;
  303.                 } else {
  304.                     theCell.v += theSubject.threadLength + 1 - theSubject.threadOrdinal;
  305.                 }
  306.             }
  307.             return OpenNextUnreadArticle(wind, theCell, 1, nil, false);
  308.             
  309.         case kGroup:
  310.         
  311.             SetPt(&theCell, 0, 0);
  312.             LGetSelect(true, &theCell, (**info).theList);
  313.             return OpenNextUnreadGroup(wind, theCell);
  314.             
  315.     }
  316.     return noErr;
  317. }
  318.  
  319.  
  320.  
  321. /*----------------------------------------------------------------------------
  322.     DoNextGroup 
  323.     
  324.     Handle the "Next Group" command.
  325.             
  326.     Entry:    wind = pointer to article, subject, or group window.
  327.     
  328.     Exit:    function result = error code.
  329. ----------------------------------------------------------------------------*/
  330.  
  331. OSErr DoNextGroup (WindowPtr wind)
  332. {
  333.     TWindow **info;
  334.     WindowPtr parent;
  335.     short index;
  336.     Cell theCell;
  337.     OSErr err = noErr;
  338.     
  339.     info = (TWindow**)GetWRefCon(wind);
  340.     
  341.     switch ((**info).kind) {
  342.     
  343.         case kArticle:
  344.         
  345.             parent = (**info).parentWindow;
  346.             if (parent == nil) return noErr;
  347.             err = DoClose(wind);
  348.             if (err != noErr) return err;
  349.             wind = parent;
  350.             info = (TWindow**)GetWRefCon(wind);
  351.             /* fall through to kSubject case */;
  352.             
  353.         case kSubject:
  354.         
  355.             MarkAllSubjects(wind, true);
  356.             parent = (**info).parentWindow;
  357.             index = (**info).parentGroup;
  358.             err = DoClose(wind);
  359.             if (err != noErr) return err;
  360.             wind = parent;
  361.             FindParentCell(wind, index, &theCell);
  362.             theCell.v++;
  363.             return OpenNextUnreadGroup(wind, theCell);
  364.             
  365.         case kGroup:
  366.         
  367.             SetPt(&theCell, 0, 0);
  368.             LGetSelect(true, &theCell, (**info).theList);
  369.             return OpenNextUnreadGroup(wind, theCell);
  370.             
  371.     }
  372.     return noErr;
  373. }
  374.